<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en-US">
<head>
<!-- GenHTML revision 25226-->
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Creating a Custom Validator - The Java EE 6 Tutorial</title>
<meta name="robots" content="index,follow">
<meta name="robots" content="index,follow">
<meta name="date" content="2011-07-01">
<link rel="stylesheet" type="text/css" href="css/default.css">
<link rel="stylesheet" type="text/css" href="css/ipg.css">
<link rel="stylesheet" type="text/css" href="css/javaeetutorial.css">
</head>

<body>

<table border="0" cellpadding="5" cellspacing="0" width="100%">
<tbody>
   <tr valign="top">
      <td width="400px"><p class="toc level1"><a href="docinfo.html">Document Information</a></p>
<p class="toc level1 tocsp"><a href="gexaf.html">Preface</a></p>
<p class="toc level1 tocsp"><a href="gfirp.html">Part&nbsp;I&nbsp;Introduction</a></p>
<p class="toc level2"><a href="bnaaw.html">1.&nbsp;&nbsp;Overview</a></p>
<p class="toc level2"><a href="gfiud.html">2.&nbsp;&nbsp;Using the Tutorial Examples</a></p>
<p class="toc level1 tocsp"><a href="bnadp.html">Part&nbsp;II&nbsp;The Web Tier</a></p>
<p class="toc level2"><a href="bnadr.html">3.&nbsp;&nbsp;Getting Started with Web Applications</a></p>
<p class="toc level2"><a href="bnaph.html">4.&nbsp;&nbsp;JavaServer Faces Technology</a></p>
<p class="toc level2"><a href="giepx.html">5.&nbsp;&nbsp;Introduction to Facelets</a></p>
<p class="toc level2"><a href="gjddd.html">6.&nbsp;&nbsp;Expression Language</a></p>
<p class="toc level2"><a href="bnaqz.html">7.&nbsp;&nbsp;Using JavaServer Faces Technology in Web Pages</a></p>
<p class="toc level2"><a href="gjcut.html">8.&nbsp;&nbsp;Using Converters, Listeners, and Validators</a></p>
<p class="toc level2"><a href="bnatx.html">9.&nbsp;&nbsp;Developing with JavaServer Faces Technology</a></p>
<p class="toc level2"><a href="gkmaa.html">10.&nbsp;&nbsp;JavaServer Faces Technology Advanced Concepts</a></p>
<p class="toc level2"><a href="bnawo.html">11.&nbsp;&nbsp;Configuring JavaServer Faces Applications</a></p>
<p class="toc level2"><a href="gkiow.html">12.&nbsp;&nbsp;Using Ajax with JavaServer Faces Technology</a></p>
<p class="toc level2"><a href="gkhxa.html">13.&nbsp;&nbsp;Advanced Composite Components</a></p>
<p class="toc level2"><a href="bnavg.html">14.&nbsp;&nbsp;Creating Custom UI Components</a></p>
<p class="toc level3"><a href="bnavh.html">Determining Whether You Need a Custom Component or Renderer</a></p>
<p class="toc level4"><a href="bnavh.html#bnavi">When to Use a Custom Component</a></p>
<p class="toc level4"><a href="bnavh.html#bnavj">When to Use a Custom Renderer</a></p>
<p class="toc level4"><a href="bnavh.html#bnavk">Component, Renderer, and Tag Combinations</a></p>
<p class="toc level3 tocsp"><a href="bnavt.html">Steps for Creating a Custom Component</a></p>
<p class="toc level3"><a href="bnavu.html">Creating Custom Component Classes</a></p>
<p class="toc level4"><a href="bnavu.html#bnavv">Specifying the Component Family</a></p>
<p class="toc level4"><a href="bnavu.html#bnavw">Performing Encoding</a></p>
<p class="toc level4"><a href="bnavu.html#bnavx">Performing Decoding</a></p>
<p class="toc level4"><a href="bnavu.html#bnavy">Enabling Component Properties to Accept Expressions</a></p>
<p class="toc level4"><a href="bnavu.html#bnavz">Saving and Restoring State</a></p>
<p class="toc level3 tocsp"><a href="bnawa.html">Delegating Rendering to a Renderer</a></p>
<p class="toc level4"><a href="bnawa.html#bnawb">Creating the Renderer Class</a></p>
<p class="toc level4"><a href="bnawa.html#bnawc">Identifying the Renderer Type</a></p>
<p class="toc level3 tocsp"><a href="bnawd.html">Handling Events for Custom Components</a></p>
<p class="toc level3"><a href="bnawe.html">Creating the Component Tag Handler</a></p>
<p class="toc level4"><a href="bnawe.html#bnawf">Retrieving the Component Type</a></p>
<p class="toc level4"><a href="bnawe.html#bnawg">Setting Component Property Values</a></p>
<p class="toc level5"><a href="bnawe.html#bnawh">Getting the Attribute Values</a></p>
<p class="toc level5"><a href="bnawe.html#bnawi">Setting the Component Property Values</a></p>
<p class="toc level4 tocsp"><a href="bnawe.html#bnawl">Providing the Renderer Type</a></p>
<p class="toc level4"><a href="bnawe.html#bnawm">Releasing Resources</a></p>
<p class="toc level3 tocsp"><a href="bnawn.html">Defining the Custom Component Tag in a Tag Library Descriptor</a></p>
<p class="toc level3"><a href="bnaus.html">Creating a Custom Converter</a></p>
<p class="toc level3"><a href="bnaut.html">Implementing an Event Listener</a></p>
<p class="toc level4"><a href="bnaut.html#bnauu">Implementing Value-Change Listeners</a></p>
<p class="toc level4"><a href="bnaut.html#bnauv">Implementing Action Listeners</a></p>
<div id="scrolltoc" class="onpage">
<p class="toc level3 tocsp"><a href="">Creating a Custom Validator</a></p>
<p class="toc level4"><a href="#bnaux">Implementing the Validator Interface</a></p>
<p class="toc level4"><a href="#bnauy">Creating a Custom Tag</a></p>
<p class="toc level5"><a href="#bnauz">Writing the Tag Handler</a></p>
<p class="toc level5"><a href="#bnava">Writing the Tag Library Descriptor</a></p>
</div>
<p class="toc level3 tocsp"><a href="bnatt.html">Using Custom Objects</a></p>
<p class="toc level4"><a href="bnatt.html#bnatu">Using a Custom Converter</a></p>
<p class="toc level4"><a href="bnatt.html#bnatv">Using a Custom Validator</a></p>
<p class="toc level4"><a href="bnatt.html#bnatw">Using a Custom Component</a></p>
<p class="toc level3 tocsp"><a href="bnatg.html">Binding Component Values and Instances to External Data Sources</a></p>
<p class="toc level4"><a href="bnatg.html#bnati">Binding a Component Value to a Property</a></p>
<p class="toc level4"><a href="bnatg.html#bnatj">Binding a Component Value to an Implicit Object</a></p>
<p class="toc level4"><a href="bnatg.html#bnatl">Binding a Component Instance to a Bean Property</a></p>
<p class="toc level3 tocsp"><a href="bnatm.html">Binding Converters, Listeners, and Validators to Managed Bean Properties</a></p>
<p class="toc level2 tocsp"><a href="bnafd.html">15.&nbsp;&nbsp;Java Servlet Technology</a></p>
<p class="toc level2"><a href="bnaxu.html">16.&nbsp;&nbsp;Internationalizing and Localizing Web Applications</a></p>
<p class="toc level1 tocsp"><a href="bnayk.html">Part&nbsp;III&nbsp;Web Services</a></p>
<p class="toc level2"><a href="gijti.html">17.&nbsp;&nbsp;Introduction to Web Services</a></p>
<p class="toc level2"><a href="bnayl.html">18.&nbsp;&nbsp;Building Web Services with JAX-WS</a></p>
<p class="toc level2"><a href="giepu.html">19.&nbsp;&nbsp;Building RESTful Web Services with JAX-RS</a></p>
<p class="toc level2"><a href="gjjxe.html">20.&nbsp;&nbsp;Advanced JAX-RS Features</a></p>
<p class="toc level2"><a href="gkojl.html">21.&nbsp;&nbsp;Running the Advanced JAX-RS Example Application</a></p>
<p class="toc level1 tocsp"><a href="bnblr.html">Part&nbsp;IV&nbsp;Enterprise Beans</a></p>
<p class="toc level2"><a href="gijsz.html">22.&nbsp;&nbsp;Enterprise Beans</a></p>
<p class="toc level2"><a href="gijre.html">23.&nbsp;&nbsp;Getting Started with Enterprise Beans</a></p>
<p class="toc level2"><a href="gijrb.html">24.&nbsp;&nbsp;Running the Enterprise Bean Examples</a></p>
<p class="toc level2"><a href="bnbpk.html">25.&nbsp;&nbsp;A Message-Driven Bean Example</a></p>
<p class="toc level2"><a href="gkcqz.html">26.&nbsp;&nbsp;Using the Embedded Enterprise Bean Container</a></p>
<p class="toc level2"><a href="gkidz.html">27.&nbsp;&nbsp;Using Asynchronous Method Invocation in Session Beans</a></p>
<p class="toc level1 tocsp"><a href="gjbnr.html">Part&nbsp;V&nbsp;Contexts and Dependency Injection for the Java EE Platform</a></p>
<p class="toc level2"><a href="giwhb.html">28.&nbsp;&nbsp;Introduction to Contexts and Dependency Injection for the Java EE Platform</a></p>
<p class="toc level2"><a href="gjbls.html">29.&nbsp;&nbsp;Running the Basic Contexts and Dependency Injection Examples</a></p>
<p class="toc level2"><a href="gjehi.html">30.&nbsp;&nbsp;Contexts and Dependency Injection for the Java EE Platform: Advanced Topics</a></p>
<p class="toc level2"><a href="gkhre.html">31.&nbsp;&nbsp;Running the Advanced Contexts and Dependency Injection Examples</a></p>
<p class="toc level1 tocsp"><a href="bnbpy.html">Part&nbsp;VI&nbsp;Persistence</a></p>
<p class="toc level2"><a href="bnbpz.html">32.&nbsp;&nbsp;Introduction to the Java Persistence API</a></p>
<p class="toc level2"><a href="gijst.html">33.&nbsp;&nbsp;Running the Persistence Examples</a></p>
<p class="toc level2"><a href="bnbtg.html">34.&nbsp;&nbsp;The Java Persistence Query Language</a></p>
<p class="toc level2"><a href="gjitv.html">35.&nbsp;&nbsp;Using the Criteria API to Create Queries</a></p>
<p class="toc level2"><a href="gkjiq.html">36.&nbsp;&nbsp;Creating and Using String-Based Criteria Queries</a></p>
<p class="toc level2"><a href="gkjjf.html">37.&nbsp;&nbsp;Controlling Concurrent Access to Entity Data with Locking</a></p>
<p class="toc level2"><a href="gkjia.html">38.&nbsp;&nbsp;Improving the Performance of Java Persistence API Applications By Setting a Second-Level Cache</a></p>
<p class="toc level1 tocsp"><a href="gijrp.html">Part&nbsp;VII&nbsp;Security</a></p>
<p class="toc level2"><a href="bnbwj.html">39.&nbsp;&nbsp;Introduction to Security in the Java EE Platform</a></p>
<p class="toc level2"><a href="bncas.html">40.&nbsp;&nbsp;Getting Started Securing Web Applications</a></p>
<p class="toc level2"><a href="bnbyk.html">41.&nbsp;&nbsp;Getting Started Securing Enterprise Applications</a></p>
<p class="toc level1 tocsp"><a href="gijue.html">Part&nbsp;VIII&nbsp;Java EE Supporting Technologies</a></p>
<p class="toc level2"><a href="gijto.html">42.&nbsp;&nbsp;Introduction to Java EE Supporting Technologies</a></p>
<p class="toc level2"><a href="bncih.html">43.&nbsp;&nbsp;Transactions</a></p>
<p class="toc level2"><a href="bncjh.html">44.&nbsp;&nbsp;Resource Connections</a></p>
<p class="toc level2"><a href="bncdq.html">45.&nbsp;&nbsp;Java Message Service Concepts</a></p>
<p class="toc level2"><a href="bncgv.html">46.&nbsp;&nbsp;Java Message Service Examples</a></p>
<p class="toc level2"><a href="gkahp.html">47.&nbsp;&nbsp;Advanced Bean Validation Concepts and Examples</a></p>
<p class="toc level2"><a href="gkeed.html">48.&nbsp;&nbsp;Using Java EE Interceptors</a></p>
<p class="toc level1 tocsp"><a href="gkgjw.html">Part&nbsp;IX&nbsp;Case Studies</a></p>
<p class="toc level2"><a href="gkaee.html">49.&nbsp;&nbsp;Duke's Tutoring Case Study Example</a></p>
<p class="toc level1 tocsp"><a href="idx-1.html">Index</a></p>
</td>
      <td width="10px">&nbsp;</td>
      <td>
         <div class="header">
             <div class="banner">
                <table width="100%" border="0" cellpadding="5" cellspacing="0">
                   <tbody>
                      <tr>
                         <td valign="bottom"><p class="Banner">The Java EE 6 Tutorial
</p></td>
                         <td align="right"  valign="bottom"><img src="graphics/javalogo.png" alt="Java Coffee Cup logo"></td>
                      </tr>
                   </tbody>
                </table>
             </div>

             <div class="header-links">
	         <a href="./index.html">Home</a> | 
<a href="../information/download.html">Download</a> | 
<a href="./javaeetutorial6.pdf">PDF</a> | 
<a href="../information/faq.html">FAQ</a> | 
<a href="http://download.oracle.com/javaee/feedback.htm">Feedback</a>

             </div>
             <div class="navigation">
                 <a href="bnaut.html"><img src="graphics/leftButton.gif" border="0" alt="Previous" title="Previous"></a>
                 <a href="p1.html"><img src="graphics/upButton.gif" border="0" alt="Contents" title="Contents"></a>
                 <a href="bnatt.html"><img src="graphics/rightButton.gif" border="0" alt="Next" title="Next"></a>
             </div>
         </div>

	 <div class="maincontent">      	 
             

<a name="bnauw"></a><h2>Creating a Custom Validator</h2>
<a name="indexterm-972"></a><p>If the standard validators or Bean Validation don&rsquo;t perform the validation checking you
need, you can create a custom validator to validate user input. There are
two ways to implement validation code:</p>


<ul><li><p>Implement a managed bean method that performs the validation.</p>

</li>
<li><p><a name="indexterm-973"></a>Provide an implementation of the <tt>Validator</tt> interface to perform the validation.</p>

</li></ul>
<p><a href="bnavb.html#bnave">Writing a Method to Perform Validation</a> explains how to implement a managed bean method to perform validation. The
rest of this section explains how to implement the <tt>Validator</tt> interface.</p>

<p>If you choose to implement the <tt>Validator</tt> interface and you want to allow
the page author to configure the validator&rsquo;s attributes from the page, you also
must create a custom tag for registering the validator on a component.</p>

<p><a name="indexterm-974"></a><a name="indexterm-975"></a>If you prefer to configure the attributes in the <tt>Validator</tt> implementation, you
can forgo creating a custom tag and instead let the page author register
the validator on a component using the <tt>validator</tt> tag, as described in
<a href="bnatt.html#bnatv">Using a Custom Validator</a>.</p>

<p>You can also create a managed bean property that accepts and returns the
<tt>Validator</tt> implementation you create, as described in <a href="bnaty.html#bnaul">Writing Properties Bound to Converters, Listeners, or Validators</a>. You can use the <tt>validator</tt>
tag&rsquo;s binding attribute to bind the <tt>Validator</tt> implementation to the managed bean property.</p>

<p>Usually, you will want to display an error message when data fails
validation. You need to store these error messages in a resource bundle.</p>

<p><a name="indexterm-976"></a>After creating the resource bundle, you have two ways to make the messages
available to the application. You can queue the error messages onto the <tt>FacesContext</tt>
programmatically, or you can register the error messages in the application configuration resource file,
as explained in <a href="bnaxb.html">Registering Custom Error Messages</a>.</p>

<p>For example, an e-commerce application might use a general-purpose custom validator called <tt>FormatValidator.java</tt>
to validate input data against a format pattern that is specified in the
custom validator tag. This validator would be used with a Credit Card Number
field on a Facelets page. Here is the custom validator tag:</p>

<pre>&lt;mystore:formatValidator
     formatPatterns="9999999999999999|9999 9999 9999 9999|
        9999-9999-9999-9999"/></pre><p>According to this validator, the data entered in the field must be
one of the following:</p>


<ul><li><p>A 16&ndash;digit number with no spaces</p>

</li>
<li><p>A 16&ndash;digit number with a space between every four digits</p>

</li>
<li><p>A 16&ndash;digit number with hyphens between every four digits</p>

</li></ul>
<p>The rest of this section describes how this validator would be implemented and
how to create a custom tag so that the page author can
register the validator on a component.</p>



<a name="bnaux"></a><h3>Implementing the Validator Interface</h3>
<a name="indexterm-977"></a><p><a name="indexterm-978"></a><a name="indexterm-979"></a><a name="indexterm-980"></a>A <tt>Validator</tt> implementation must contain a constructor, a set of accessor methods for
any attributes on the tag, and a <tt>validate</tt> method, which overrides the <tt>validate</tt>
method of the <tt>Validator</tt> interface.</p>

<p>The <tt>FormatValidator</tt> class also defines accessor methods for setting the <tt>formatPatterns</tt> attribute, which specifies
the acceptable format patterns for input into the fields. In addition, the class
overrides the <tt>validate</tt> method of the <tt>Validator</tt> interface. This method validates the
input and also accesses the custom error messages to be displayed when the
<tt>String</tt> is invalid.</p>

<p><a name="indexterm-981"></a>The <tt>validate</tt> method performs the actual validation of the data. It takes the
<tt>FacesContext</tt> instance, the component whose data needs to be validated, and the value
that needs to be validated. A validator can validate only data of a
component that implements <tt>EditableValueHolder</tt>.</p>

<p>Here is an implementation of the <tt>validate</tt> method:</p>

<pre>@FacesValidator
public void validate(FacesContext context, UIComponent component, Object toValidate) {

    boolean valid = false;
    String value = null;
    if ((context == null) || (component == null)) {
        throw new NullPointerException();
    }
    if (!(component instanceof UIInput)) {
        return;
    }
    if ( null == formatPatternsList || null == toValidate) {
        return;
    }
    value = toValidate.toString();
    //validate the value against the list of valid patterns.
    Iterator patternIt = formatPatternsList.iterator();
    while (patternIt.hasNext()) {
        valid = isFormatValid(
            ((String)patternIt.next()), value);
        if (valid) {
            break;
        }
    }
    if ( !valid ) {
        FacesMessage errMsg =
            MessageFactory.getMessage(context,
                FORMAT_INVALID_MESSAGE_ID,
                     (new Object[] {formatPatterns}));
            throw new ValidatorException(errMsg);
    }
}</pre><p>The <tt>@FacesValidator</tt> annotation registers the above method as a converter with the JavaServer
Faces implementation. This method gets the local value of the component and converts
it to a <tt>String</tt>. It then iterates over the <tt>formatPatternsList</tt> list, which is the
list of acceptable patterns as specified in the <tt>formatPatterns</tt> attribute of the custom
validator tag.</p>

<p><a name="indexterm-982"></a>While iterating over the list, this method checks the pattern of the component&rsquo;s
local value against the patterns in the list. If the pattern of the
local value does not match any pattern in the list, this method generates
an error message. It then passes the message to the constructor of <tt>ValidatorException</tt>.
Eventually the message is queued onto the <tt>FacesContext</tt> instance so that the message is
displayed on the page during the Render Response phase.</p>

<p><a name="indexterm-983"></a><a name="indexterm-984"></a><a name="indexterm-985"></a><a name="indexterm-986"></a>The error messages are retrieved from the <tt>Application</tt> instance by <tt>MessageFactory</tt>. An application
that creates its own custom messages must provide a class, such as <tt>MessageFactory</tt>, that
retrieves the messages from the <tt>Application</tt> instance.</p>

<p><a name="indexterm-987"></a><a name="indexterm-988"></a>The <tt>getMessage(FacesContext, String, Object)</tt> method of <tt>MessageFactory</tt> takes a <tt>FacesContext</tt>, a static <tt>String</tt> that represents the
key into the <tt>Properties</tt> file, and the format pattern as an <tt>Object</tt>. The
key corresponds to the static message ID in the <tt>FormatValidator</tt> class:</p>

<pre>public static final String FORMAT_INVALID_MESSAGE_ID =
     "FormatInvalid";
}</pre><p>When the error message is displayed, the format pattern will be substituted for
the <tt>{0}</tt> in the error message, which, in English, is as follows:</p>

<pre>Input must match one of the following patterns {0}</pre><p>JavaServer Faces applications can save the state of validators and components on either
the client or the server. <a href="bnaxj.html#bnaxn">Specifying Where State Is Saved</a> explains how to configure your application
to save state on either the client or the server.</p>

<p>If your JavaServer Faces application saves state on the client (which is the
default), you need to make the <tt>Validator</tt> implementation implement <tt>StateHolder</tt> as well as
<tt>Validator</tt>. In addition to implementing <tt>StateHolder</tt>, the <tt>Validator</tt> implementation needs to implement the <tt>saveState(FacesContext)</tt>
and <tt>restoreState(FacesContext, Object)</tt> methods of <tt>StateHolder</tt>. With these methods, the <tt>Validator</tt> implementation tells the JavaServer
Faces implementation which attributes of the <tt>Validator</tt> implementation to save and restore
across multiple requests.</p>

<p>To save a set of values, you must implement the <tt>saveState(FacesContext)</tt> method.
This method is called during the Render Response phase, during which the state
of the response is saved for processing on subsequent requests. When implementing the
<tt>saveState(FacesContext)</tt> method, you need to create an array of objects and add the
values of the attributes you want to save to the array. Here is
the <tt>saveState(FacesContext)</tt> method from the custom validator class:</p>

<pre>public Object saveState(FacesContext context) {
    Object values[] = new Object[2];
    values[0] = formatPatterns;
    values[1] = formatPatternsList;
    return (values);
}</pre><p><a name="indexterm-989"></a>To restore the state saved with the <tt>saveState(FacesContext)</tt> method in preparation for the next
postback, the <tt>Validator</tt> implementation implements <tt>restoreState(FacesContext, Object)</tt>. The <tt>restoreState(FacesContext, Object)</tt> method takes the <tt>FacesContext</tt> instance
and an <tt>Object</tt> instance, which represents the array that is holding the state
for the <tt>Validator</tt> implementation. This method sets the <tt>Validator</tt> implementation&rsquo;s properties to the values
saved in the <tt>Object</tt> array. Here is the <tt>restoreState(FacesContext, Object)</tt> method from <tt>FormatValidator</tt>:</p>

<pre>public void restoreState(FacesContext context, Object state) {
    Object values[] = (Object[]) state;
    formatPatterns = (String) values[0];
    formatPatternsList = (ArrayList) values[1];
}</pre><p>As part of implementing <tt>StateHolder</tt>, the custom <tt>Validator</tt> implementation must also override the <tt>isTransient</tt>
and <tt>setTransient(boolean)</tt> methods of <tt>StateHolder</tt>. By default, <tt>transientValue</tt> is false, which means
that the <tt>Validator</tt> implementation will have its state information saved and restored. Here
are the <tt>isTransient</tt> and <tt>setTransient(boolean)</tt> methods of <tt>FormatValidator</tt>:</p>

<pre>private boolean transientValue = false;

public boolean isTransient() {
    return (this.transientValue);
}

public void setTransient(boolean transientValue) {
    this.transientValue = transientValue;
}</pre><p><a href="bnavu.html#bnavz">Saving and Restoring State</a> describes how a custom component must implement the <tt>saveState(FacesContext)</tt> and <tt>restoreState(FacesContext, Object)</tt> methods.</p>



<a name="bnauy"></a><h3>Creating a Custom Tag</h3>
<a name="indexterm-990"></a><a name="indexterm-991"></a><p><a name="indexterm-992"></a>If you implemented a <tt>Validator</tt> interface rather than implementing a managed bean method
that performs the validation, you need to do one of the following:</p>


<ul><li><p><a name="indexterm-993"></a><a name="indexterm-994"></a><a name="indexterm-995"></a><a name="indexterm-996"></a>Allow the page author to specify the <tt>Validator</tt> implementation to use with the <tt>validator</tt> tag. In this case, the <tt>Validator</tt> implementation must define its own properties. <a href="bnatt.html#bnatv">Using a Custom Validator</a> explains how to use the <tt>validator</tt> tag.</p>

</li>
<li><p>Create a custom tag that provides attributes for configuring the properties of the validator from the page. Because the <tt>Validator</tt> implementation from the preceding section does not define its attributes, the application developer must create a custom tag so that the page author can define the format patterns in the tag.</p>

</li></ul>
<p>To create a custom tag, you need to do two things:</p>


<ul><li><p>Write a tag handler to create and register the <tt>Validator</tt> implementation on the component.</p>

</li>
<li><p>Write a TLD file to define the tag and its attributes.</p>

</li></ul>
<p><a href="bnatt.html#bnatv">Using a Custom Validator</a> explains how to use the custom validator tag on the page.</p>



<a name="bnauz"></a><h4>Writing the Tag Handler</h4>
<p><a name="indexterm-997"></a><a name="indexterm-998"></a><a name="indexterm-999"></a>The tag handler associated with a custom validator tag must extend the <tt>ValidatorELTag</tt>
class. This class is the base class for all custom tag handlers that
create <tt>Validator</tt> instances and register them on UI components. The <tt>FormatValidatorTag</tt> class registers the
<tt>FormatValidator</tt> instance onto the component.</p>

<p>The <tt>FormatValidatorTag</tt> tag handler class does the following:</p>


<ul><li><p>Sets the ID of the validator.</p>

</li>
<li><p>Provides a set of accessor methods for each attribute defined on the tag.</p>

</li>
<li><p><a name="indexterm-1000"></a><a name="indexterm-1001"></a><a name="indexterm-1002"></a>Implements the <tt>createValidator</tt> method of the <tt>ValidatorELTag</tt> class. This method creates an instance of the validator and sets the range of values accepted by the validator.</p>

</li></ul>
<p>The <tt>formatPatterns</tt> attribute of the <tt>formatValidator</tt> tag supports literals and value expressions.
Therefore, the accessor method for this attribute in the <tt>FormatValidatorTag</tt> class must accept and
return an instance of <tt>ValueExpression</tt>:</p>

<pre>protected ValueExpression formatPatterns = null;

public void setFormatPatterns(ValueExpression fmtPatterns){
    formatPatterns = fmtPatterns;
}</pre><p>Finally, the <tt>createValidator</tt> method creates an instance of <tt>FormatValidator</tt>, extracts the value from the
<tt>formatPatterns</tt> attribute&rsquo;s value expression and sets the <tt>formatPatterns</tt> property of <tt>FormatValidator</tt> to this
value:</p>

<p>the <tt>formatPatterns</tt> property of <tt>FormatValidator</tt> to this value:</p>

<pre>protected Validator createValidator() throws JspException {
    FacesContext facesContext =
         FacesContext.getCurrentInstance();
    FormatValidator result = null;
    if(validatorID != null){
        result = (FormatValidator) facesContext.getApplication()
            .createValidator(validatorID);
    }
    String patterns = null;
    if (formatPatterns != null) {
        if (!formatPatterns.isLiteralText()) {
            patterns = (String)
             formatPatterns.getValue(facesContext.getELContext());
        } else {
            patterns = formatPatterns.getExpressionString();
        }</pre>

<a name="bnava"></a><h4>Writing the Tag Library Descriptor</h4>
<a name="indexterm-1003"></a><a name="indexterm-1004"></a><p>To define a tag, you declare it in a tag library descriptor
(TLD), which is an XML document that describes a tag library. A TLD
contains information about a library and each tag contained in it.</p>

<p>The custom validator tag is defined in a TLD that contains a
tag definition for <tt>formatValidator</tt>:</p>

<pre>&lt;tag>
    &lt;tag-name>validator&lt;/tag-name>
    &lt;validator>
        &lt;validator-id>formatValidator&lt;/validator-id>
        &lt;validator-class>dukesbookstore.validators.FormatValidator&lt;/validator-class>
    &lt;/validator>
&lt;/tag></pre><p>The <tt>tag-name</tt> element defines the name of the tag as it must be
used in a Facelets page. The <tt>validator-id</tt> element identifies the custom validator.
The <tt>validator-class</tt> element wires the custom tag to its implementation class.</p>


         </div>
         <div class="navigation">
             <a href="bnaut.html"><img src="graphics/leftButton.gif" border="0" alt="Previous" title="Previous"></a>
             <a href="p1.html"><img src="graphics/upButton.gif" border="0" alt="Contents" title="Contents"></a>
             <a href="bnatt.html"><img src="graphics/rightButton.gif" border="0" alt="Next" title="Next"></a>
         </div>

         <div class="copyright">
      	    <p>Copyright &copy; 2011, Oracle and/or its affiliates. All rights reserved. <a href="docinfo.html">Legal Notices</a></p>
      	 </div>

      </td>
   </tr>
</tbody>
</table>
</body>
</html>

